home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 6: Level 6
/
17 Bit - Level 6 (1998)(Epic Marketing)[!].iso
/
quartz
/
q0040.dms
/
q0040.adf
/
disass
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-05
|
10KB
|
431 lines
/* (c) 1990 S.Hawtin.
Permission is granted to copy this file provided
1) It is not used for commercial gain
2) This notice is included in all copies
3) Altered copies are marked as such
No liability is accepted for the contents of the file.
*/
/* A program that will dump out executable code */
#include <stdio.h>
#include <stdarg.h>
int with_data = TRUE;
int with_code = TRUE;
int with_reloc = TRUE;
int with_code_data = FALSE;
char *data_name = NULL;
FILE *in;
#define NAME_LEN 128
char name[NAME_LEN];
quit()
{/* Close down the files and exit */
fclose(in);
exit(0);
}
void
my_fread(buff,num,fptr)
char *buff;
int num;
FILE *fptr;
{/* Read some bytes into a buffer */
int i;
for(i=0;i<num;i++)
{/* The file should be buffered anyway */
buff[i] = fgetc(fptr);
if(feof(fptr))
quit();
}
}
now_printing = TRUE;
void
my_printf(str,args)
char *str;
{/* Do a printf, by putting it here we can do things like turn it off
and duplicate into another file */
va_list va_args;
va_start(va_args,str);
if(now_printing)
vprintf(str,va_args);
va_end(va_args);
}
/* Because of a new bug in the optimiser these static variables must
be left outside the function */
static char *read_buffer;
static int read_buf_len = 0;
char *
read_name(fptr,symb)
FILE *fptr;
int symb;
{/* Read the next name, preceeded by its length */
long length;
my_fread(&length,sizeof(long),in);
if(symb)
length &= 0xffffff;
if(length*sizeof(long) > read_buf_len-1)
{if(read_buffer)
free(read_buffer);
read_buffer = malloc(length*sizeof(long) + 1);
if(read_buffer==NULL)
{my_printf("malloc failed\n");
exit(20);
}
read_buf_len = length*sizeof(long) + 1;
}
my_fread(read_buffer,length*sizeof(long),in);
read_buffer[length*sizeof(long)] = '\0';
return(read_buffer);
}
void
dump_data(in)
FILE *in;
{/* Dump out some data */
unsigned char line[16];
long length;
int line_num,i,old_print;
if(!with_data)
{
old_print = now_printing;
now_printing = FALSE;
}
my_fread(&length,sizeof(long),in);
line_num = 0;
while(line_num < length/4)
{/* Full line */
my_fread(line,16,in);
my_printf(" %05x:",line_num*16);
for(i=0;i<16;i++)
{
if(i%4 == 0)
my_printf(" ");
if(i%2 == 0)
my_printf(" ");
my_printf("%02x",line[i]);
}
my_printf(" ");
for(i=0;i<16;i++)
{
my_printf("%c",(line[i]>=0x20 && line[i]<0x80)?line[i]:'.');
}
my_printf("\n");
line_num++;
}
/* Final line */
length -= line_num*4;
if(0 != length)
{/* We have a partial line */
my_fread(line,length*4,in);
my_printf(" %05x:",line_num*16);
for(i=0;i<16;i++)
{
if(i%4 == 0)
my_printf(" ");
if(i%2 == 0)
my_printf(" ");
if(length*4<=i)
my_printf(" ");
else
my_printf("%02x",line[i]);
}
my_printf(" ");
for(i=0;i<length*4;i++)
{
my_printf("%c",(line[i]>=0x20 && line[i]<0x80)?line[i]:'.');
}
my_printf("\n");
}
if(!with_data)
{
now_printing = old_print;
}
}
void
dump_code(in)
FILE *in;
{/* Dump executable code */
int old_print;
if (!with_code)
{old_print = now_printing;
now_printing = FALSE;
}
if(with_code_data)
dump_data(in);
else
{/* Dump the code as real code, not done yet */
long length;
my_fread(&length,sizeof(long),in);
disass(length,in);
}
if(!with_code)
{
now_printing = old_print;
}
}
void
dump_reloc(num,in)
long num;
FILE *in;
{/* Dump relocations on multiple lines */
int i;
long val;
int old_print;
i=0;
if(num>4)
{
if (!with_reloc)
{old_print = now_printing;
now_printing = FALSE;
}
while(num>0)
{if (i%5 == 0)
my_printf("\n ");
my_fread(&val,sizeof(long),in);
my_printf(" %08x",val);
--num;
++i;
}
if (!with_reloc)
{
now_printing = old_print;
}
}
else
while(num>0)
{my_fread(&val,sizeof(long),in);
my_printf(" %08x",val);
--num;
}
my_printf("\n");
}
void
dump_reloc32(in)
FILE *in;
{/* Inter hunk relocation information */
long num,val;
my_fread(&num,sizeof(long),in);
while(num!=0)
{/* Dump this relocation */
my_fread(&val,sizeof(long),in);
my_printf(" Hunk %2ld @ ",val);
dump_reloc(num,in);
my_fread(&num,sizeof(long),in);
}
}
void
dump_ext(in)
FILE *in;
{/* Dump external symbol table */
int next;
long num;
next = getc(in);
ungetc(next,in);
while(next!=0)
{/* Dump out this symbol */
my_printf(" \"%s\" ",read_name(in,TRUE));
my_fread(&num,sizeof(long),in);
switch(next)
{
case 0x02:
my_printf("Abs Val ");
case 0x01:
my_printf(" = %08x\n",num);
break;
case 0x83:
my_printf(" 16 bit ");
case 0x81:
my_printf(" @ ");
dump_reloc(num,in);
break;
default:
my_printf("### ERROR ### Ext code of %02x\n",next);
}
next = getc(in);
ungetc(next,in);
}
my_fread(&num,sizeof(long),in);
if(num!=0)
my_printf("### ERROR ### End of Ext %08x\n",num);
}
void
dump_symbol(in)
FILE *in;
{/* Dump symbol entries */
char *name;
long val;
do {
name = read_name(in,TRUE);
if(*name)
{my_fread(&val,sizeof(long),in);
my_printf(" \"%s\" = %08x\n",name,val);
}
} while(*name);
}
void
dump_header(in)
FILE *in;
{/* Dump the hunk header */
long val1,val2,val3,val4;
my_fread(&val1,sizeof(long),in);
my_fread(&val2,sizeof(long),in);
my_fread(&val3,sizeof(long),in);
my_fread(&val4,sizeof(long),in);
/* The first seems to always be 0 */
my_printf(" %ld %ld %ld %ld ",val1,val2,val3,val4);
dump_reloc(val2,in);
}
void
doopts(argc,argv)
int argc;
char **argv;
{/* Get the command line options */
int i;
for(i=1;i<argc;i++)
{if(argv[i][0] == '-')
{
switch(argv[i][1])
{
case 'h': case 'H':
/* Ignore the actual data */
with_data = FALSE;
with_code = FALSE;
with_reloc = FALSE;
break;
case 'L': case 'l':
with_code_data = TRUE;
break;
default:
/* Tell the user the real set of options */
goto out_options;
}
}
else if(data_name==NULL)
{/* Data file name */
data_name = argv[i];
}
else
{
out_options:
my_printf("Options are\n\n");
my_printf(" -h\n");
my_printf(" -l\n");
my_printf(" <objectfile>\n");
exit(20);
}
}
}
void
main(argc,argv)
int argc;
char **argv;
{/* dump out what the contents are */
int count;
long len;
doopts(argc,argv);
if(data_name==NULL)
{printf("Need file name to read\n");
exit(20);
}
in = fopen(data_name,"r");
if(in==NULL)
{printf("Cannot open \"%s\"\n",data_name);
exit(20);
}
/* So we can now get down to the serious buisness of scanning the
data file */
count = 0;
while(TRUE)
{/* Keep scanning until we have an end of file or we find
a final marker */
long flag;
my_fread(&flag,4,in);
switch(flag)
{case 0x3e7:
my_printf("Hunk PU Name \"%s\"\n",read_name(in,FALSE));
break;
case 0x3e8:
my_printf("Hunk Name \"%s\"\n",read_name(in,FALSE));
break;
case 0x3e9:
my_printf("Hunk Code Public\n");
dump_code(in);
break;
case 0x3ea:
my_printf("Hunk Data Public\n");
dump_data(in);
break;
case 0x3eb:
my_fread(&len,sizeof(long),in);
my_printf("Hunk BSS Public %x\n",len*4);
break;
case 0x3ec:
my_printf("Hunk Reloc 32\n");
dump_reloc32(in);
break;
case 0x3ef:
my_printf("Hunk Ext\n");
dump_ext(in);
break;
case 0x3f0:
my_printf("Hunk Symbol\n");
dump_symbol(in);
break;
case 0x3f2:
my_printf("Hunk End\n");
break;
case 0x3f3:
my_printf("Hunk Header\n");
dump_header(in);
break;
default:
count++;
my_printf("%08x ",flag);
if((count%4) == 0)
my_printf("\n");
}
}
}